package com.aneliya.io.xml;

import java.util.UUID;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

import com.aneliya.model.ErrorType;
import com.aneliya.model.Message;
import com.aneliya.model.MessageType;
import com.aneliya.model.User;

public class XMLMessageParser {
	
	public Message parseXMLMessage(Document messageDocument) {
		Element messageElement = messageDocument.getDocumentElement();
		Node typeAttribute = messageElement.getAttributes().getNamedItem("type");
		MessageType messageType = MessageType.valueOf(typeAttribute.getNodeValue());
		
		switch (messageType) {
		case TEXT:
			return parseTextMessageDocument(messageDocument);
		case REGISTER:
			return parseRegisterMessageDocument(messageDocument);
		case LOGIN:
			return parseLoginMessageDocument(messageDocument);
		case LOGOUT:
			return parseLogoutMessageDocument(messageDocument);
		case ERROR:
			return parseErrorMessageDocument(messageDocument);
		case KEEP_ALIVE:
			return parseKeepAliveMessageDocument(messageDocument);

		default:
			return null;
		}
	}

	private Message parseTextMessageDocument(Document messageDocument) {
		Element messageElement = messageDocument.getDocumentElement();
		Node typeAttribute = messageElement.getAttributes().getNamedItem("type");
		MessageType messageType = MessageType.valueOf(typeAttribute.getNodeValue());
		
		Node usernameAttribute = messageElement.getAttributes().getNamedItem("username");
		String username = usernameAttribute.getNodeValue();
		
		Node tokenElement = messageElement.getElementsByTagName("token").item(0);
		Text tokenText = (Text) tokenElement.getFirstChild();
		UUID token = UUID.fromString(tokenText.getNodeValue());
		
		Node messageDataElement = messageElement.getElementsByTagName("message_data").item(0);
		Text messageDataText = (Text) messageDataElement.getFirstChild();
		Object messageData = messageDataText.getNodeValue();
		
		Message message = new Message(username, messageData);
		message.setMessageType(messageType );
		message.setToken(token);

		return message;
	}

	private Message parseRegisterMessageDocument(Document messageDocument) {
		Element messageElement = messageDocument.getDocumentElement();
		Node typeAttribute = messageElement.getAttributes().getNamedItem("type");
		MessageType messageType = MessageType.valueOf(typeAttribute.getNodeValue());
		
		Node usernameElement = messageElement.getElementsByTagName("username").item(0);
		Text usernameElementText = (Text) usernameElement.getFirstChild();
		String username = usernameElementText.getNodeValue();
		
		Node passwordElement = messageElement.getElementsByTagName("password").item(0);
		Text passwordElementText = (Text) passwordElement.getFirstChild();
		String password = passwordElementText.getNodeValue();
		
		User user = new User(username, password);
		Message message = new Message(null, user);
		message.setMessageType(messageType);
		
		return message;
	}

	private Message parseLoginMessageDocument(Document messageDocument) {
		return parseRegisterMessageDocument(messageDocument);
	}

	private Message parseLogoutMessageDocument(Document messageDocument) {
		Element messageElement = messageDocument.getDocumentElement();
		Node typeAttribute = messageElement.getAttributes().getNamedItem("type");
		MessageType messageType = MessageType.valueOf(typeAttribute.getNodeValue());
		
		Node usernameAttribute = messageElement.getAttributes().getNamedItem("username");
		String username = usernameAttribute.getNodeValue();
		
		Message message = new Message(null, username);
		message.setMessageType(messageType);
		
		return message;
	}

	private Message parseErrorMessageDocument(Document messageDocument) {
		Element messageElement = messageDocument.getDocumentElement();
		Node typeAttribute = messageElement.getAttributes().getNamedItem("type");
		MessageType messageType = MessageType.valueOf(typeAttribute.getNodeName());
		
		Node errorTypeAttribute = messageElement.getAttributes().getNamedItem("errorType");
		ErrorType errorType = ErrorType.valueOf(errorTypeAttribute.getNodeValue());
		
		Message message = new Message(null, errorType);
		message.setMessageType(messageType);
		
		return message;
	}

	private Message parseKeepAliveMessageDocument(Document messageDocument) {
		Element messageElement = messageDocument.getDocumentElement();
		Node typeAttribute = messageElement.getAttributes().getNamedItem("type");
		MessageType messageType = MessageType.valueOf(typeAttribute.getNodeName());
		
		Message message = new Message(null, null);
		message.setMessageType(messageType);
		return message;
	}
	
}
